package org.supda.system.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import javax.annotation.Resource;

import org.springframework.context.annotation.Role;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.supda.system.controller.common.CommonInfo;
import org.supda.system.dao.RoleDao;
import org.supda.system.dao.UserDao;
import org.supda.system.entity.TResources;
import org.supda.system.entity.TRole;
import org.supda.system.entity.TUser;
import org.supda.system.service.UserService;
import org.supda.system.util.CommonUtils;
import org.supda.system.util.DataTablePageUtil;
import org.supda.system.util.EntityUpdataUtils;
import org.supda.system.util.PageUtil;
import org.supda.system.util.PasswordUtil;

@Service("UserService")
@Transactional
public class UserServiceImpl implements UserService{

	@Resource UserDao userDao;
	@Resource RoleDao roleDao;
	
	@Override
	public List<TUser> listUsers() {
		List<TUser> list =  userDao.find("From TUser");
		System.out.println("用户列表数据:"+list);
		return list;
	}
	
	@Override
	public TUser findById(Long id) {
		return userDao.get(TUser.class, id);
	}

	@Override
	public List<TUser> findByAccountName(String accountName) {
		
		return userDao.find("From TUser WHERE accountName=?", new Object[]{accountName});
		
	}

	@Override
	public TUser findByUsername(String accountName) {
		return findByAccountName(accountName).get(0);
	}

	@Override
	public Set<TRole> findRoles(String accountName) {
		Set<TRole> roles = new HashSet<TRole>();
		
		for(TRole role:findByAccountName(accountName).get(0).getTRoles())
				roles.add(role);
				
		return roles;
	}

	@Override
	public Set<TResources> findResources(String username) {
		Set<TResources> Resources = new HashSet<TResources>();
		
		for(TRole role:findRoles(username))
			for(TResources res : role.getTResourceses())
				Resources.add(res);
					
		return Resources;
	}

	@Override
	public TUser createUser(TUser user) {
		
		fillBlankUserValue(user);
		
		return findById((Long)userDao.save(user));
	}

	/**
	 * 默认值设置
	 * @param user
	 */
	private void fillBlankUserValue(TUser user) {
		
		//创建时间
		user.setCreateTime(new Date());
		//认证盐
		user.setCredentialsSalt(UUID.randomUUID().toString());
		//默认不锁定
		user.setLocked("1");
		//随机盐
		user.setRandomSalt(UUID.randomUUID().toString());
		//有效
		user.setValid(CommonInfo.VALID);
		//密码
		user.setPassword(PasswordUtil.getPassword("123456", user.getCredentialsSalt()));
	}

	@Override
	public void changePassword(Long userId, String newPassword) {
		
		TUser user = findById(userId);
		
		user.setPassword(PasswordUtil.getPassword(newPassword, user.getCredentialsSalt()));
		
		userDao.update(user);
	}

	@Override
	public void correlationRoles(Long userId, Long... roleIds) {
		
		 TUser user = userDao.get(TUser.class, userId);
		
		for(Long roleId : roleIds){
			 TRole role = roleDao.get(TRole.class, roleId);
			 role.getTUsers().add(user);
			 user.getTRoles().add(role);
		}
		
	}

	@Override
	public void unCorrelationRoles(Long userId, Long... roleIds) {
		
		TUser user = userDao.get(TUser.class, userId);
			
			for(Long roleId : roleIds){
				 TRole role = roleDao.get(TRole.class, roleId);
				 role.getTUsers().remove(user);
				 user.getTRoles().remove(role);
			}
	}

	@Override
	public PageUtil listByPage(PageUtil page, TUser user) {

		if(page==null){page = new PageUtil();}
		
		 return userDao.listByPage(page, user);
	}

	@Override
	public void listByDataTable(DataTablePageUtil<TUser> dtp) {
		 userDao.listByDataTable(dtp, TUser.class);
	}

	@Override
	public Set<TResources> findResources(String accountName, Long menuId) {
		Set<TResources> Resources = new HashSet<TResources>();
		
		for(TRole role:findRoles(accountName)){
			for(TResources res : role.getTResourceses()){
				if(res.getParentId().equals(menuId))
				Resources.add(res);
			}
		}
		return Resources;
	}

	@Override
	public String locked(Long id) {
		
		String message = "";
		
		TUser user = findById(id);
		try{
			if(user!=null){
				if(Integer.parseInt(user.getLocked()) == 1){
					user.setLocked("0");
					message = "locked";
				}else if(Integer.parseInt(user.getLocked()) == 0){
					user.setLocked("1");
					message = "unlocked";
				}
				
				userDao.update(user);
			}
			
		}catch(Exception e){
			message = "error";
		}
		
		return message;
	}

	@Override
	public String delete(Long id) {
		
		String message = "";
		
		try{
			TUser tUser = findById(id);
			
			if(tUser != null){
				tUser.setValid(CommonInfo.INVAILD);
				userDao.update(tUser);
			}
			message = "success";
		}catch(Exception e){
			message = "fail";
		}
		
		return message;
	}
	
	public void updateCorrelationRoles(Long userId , Long ...roleIds){
		
		//查询出用户信息
		TUser user = findById(userId);
		
		if(user == null ) throw new RuntimeException("不存在该user对象");
		
		if(user.getTRoles()==null&&roleIds==null)
			return ;
		
		//若该用户没有指定角色
		if(user.getTRoles()==null) {
			correlationRoles(user.getId(), roleIds);
			return ;
		}
		
		//比对roleIds
		Long[] oldRoleIds = new Long[user.getTRoles().size()];		
		
		int i = 0;
		for(TRole role : user.getTRoles()){
			oldRoleIds[i++] = role.getId();
		}
		
		if(roleIds == null ){
			unCorrelationRoles(userId, oldRoleIds);
			return ;
		}
		
		//需要添加的关系
		Long[] delElement = getTargetElement(oldRoleIds , roleIds);
		//需要删除的关系
		Long[] addElement = getTargetElement(roleIds , oldRoleIds);
		
		unCorrelationRoles(user.getId(), delElement);
		correlationRoles(user.getId(), addElement);
		
	}

	/**
	 * 判断oldRoleIds是否包含roleIds元素
	 * @param roleIds
	 * @param oldRoleIds
	 * @return
	 */
	private Long[] getTargetElement(Long[] roleIds, Long[] oldRoleIds) {
		List<Long> list = new ArrayList<Long>();
		
		List oldroleIds = Arrays.asList(oldRoleIds);
		
		for(Long roleId : roleIds){
			
			if(!oldroleIds.contains(roleId)){
				list.add(roleId);
			}
		}
		
		return list.toArray(new Long[list.size()]);
	}

	@Override
	public void update(TUser user, Long[] roleIds) {
		
		//更新用户-角色关系
		updateCorrelationRoles(user.getId(), roleIds);
		
		TUser source = EntityUpdataUtils.update(TUser.class,findById(user.getId()), user);

		userDao.update(source);
	}
	
}
